<?php
namespace App\Services\SysRbac;

use App\Models\SysPermission;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;

class SysPermissionService
{
    /**
     * 面包屑数据
     * @var
     */
    private $breadcrumbData = [];
    /**
     * 构造函数
     */
    public function __construct()
    {
    }

    /**
     * 获取所有权限列表
     * @return mixed
     */
    public function getAllList()
    {
        $permList = SysPermission::orderBy('order_num','ASC')->orderBy('perm_id','ASC')->get()->toArray();
        $newPermList = [];
        if ($permList){
            foreach ($permList as $v){
                $newPermList[(int) $v['perm_id']] = $v;
            }
        }
        return $newPermList;
    }

    /**
     * 用于选择时的权限列表
     * @return mixed
     */
    public function getChoiceList()
    {
        $permList = SysPermission::orderBy('order_num','ASC')->orderBy('perm_id','ASC')->get()->toArray();
        return $permList;
    }

    /**
     * 获取指定权限下的权限列表
     * @param $parentId
     * @return mixed
     */
    public function getChildList($parentId)
    {
        $permList = SysPermission::where('parent_id', $parentId)->orderBy('order_num','ASC')->orderBy('perm_id','ASC')->get()->toArray();
        return $permList;
    }

    /**
     * 获取数据
     * @param $permId
     * @return mixed
     */
    public function getData($permId)
    {
        return SysPermission::findOrFail($permId)->toArray();
    }

    /**
     * 通过路由名称（权限定义）获取权限数据
     * @param $permName
     * @return mixed
     */
    public function getDataByPermName($permName)
    {
        return SysPermission::where('name', $permName)->orderBy('perm_id','desc')->firstOrFail()->toArray();
    }
    /**
     * 保存添加权限
     * @param \Request $request
     * @return bool
     */
    public function saveData($request)
    {
        if ($request->perm_id){
            $perm = SysPermission::find($request->perm_id);
        }else{
            $perm = new SysPermission;
        }
        $perm->parent_id = $request->input('parent_id', 0);
        $perm->name = $request->input('name', '');
        $perm->display_name = $request->input('display_name','');
        $perm->description = (string) $request->input('description','');
        $perm->is_public = (int) $request->input('is_public', 0);
        $perm->is_opentree = (int) $request->input('is_opentree', 0);
        $rs = $perm->save();
        $rs && $this->clearPermListCache();
        return $rs;
    }

    /**
     * 删除
     * @param $permId
     * @return mixed
     */
    public function del($permIds)
    {
        $rs = SysPermission::destroy($permIds);
        $rs && $this->clearPermListCache();
        return $rs;
    }

    /**
     * 保存排序
     * @param $parentId
     * @param $ruleId
     * @param $position
     * @return bool
     * @throws \Exception
     */
    public function setOrder($parentId, $permId, $position)
    {
        $permList = $this->getChildList($parentId);
        $orderKeyList = [];
        //第一个首先插入
        if($position == 0){
            $orderKeyList[] = $permId;
        }
        if ($permList){
            $countAuthRule = count($permList);
            foreach ($permList as $k => $v){
                //如果插入之前顺序恰当，将当前规则id强制加入
                if($k == $position){
                    $orderKeyList[] = $permId;
                }
                //非当前规则id时：按顺序排序规则ID
                if ($v['perm_id'] != $permId){
                    $orderKeyList[] = $v['perm_id'];
                }
            }
            //插入最后
            if($position == $countAuthRule - 1){
                $orderKeyList[] = $permId;
            }
        }
        if ($orderKeyList){
            DB::beginTransaction();
            try{
                foreach ($orderKeyList as $orderNum => $permId){
                    DB::table('sys_permissions')->where('perm_id', $permId)->update(['order_num'=> $orderNum, 'parent_id'=> $parentId]);
                }
                DB::commit();
                return true;
            }catch (\Exception $e){
                DB::rollBack();
                throw new \Exception($e->getMessage());
            }
        }
    }

    /**
     * 从缓存中获取权限列表
     * @return mixed
     */
    public function getCachePermList()
    {
        $cacheKey = 'syspermission_permlist';
        $cacheData = Cache::get($cacheKey);
        if (!$cacheData){
            $cacheData = $this->getAllList();
            Cache::put($cacheKey, $cacheData, 60);
        }
        return $cacheData;
    }

    /**
     * 清除权限列表缓存
     */
    public function clearPermListCache()
    {
        $cacheKey = 'syspermission_permlist';
        Cache::delete($cacheKey);
    }
    /**
     * 获取面包屑数据
     * @param $permId
     * @return array
     */
    public function getBreadcrumbData($permId)
    {
        $permList = $this->getCachePermList();
        if ($permList && isset($permList[$permId])){
            while (isset($permList[$permId])){
                array_unshift($this->breadcrumbData, $permList[$permId]);
                $permId = (int) $permList[$permId]['parent_id'];
            }
        }
        return $this->breadcrumbData;
    }

    /**
     * 获取父级权限数据，用来定位当前选中菜单
     * @param $permId
     * @return array
     */
    public function getParentPermData($permId)
    {
        $parentPermData = [];
        $permList = $this->getCachePermList();
        if (isset($permList[$permId])){
            $curPermData = $permList[$permId];
            $parentPermId = (int) $curPermData['parent_id'];
            $parentPermData = isset($permList[$parentPermId]) ? $permList[$parentPermId] : [];
        }
        return $parentPermData;
    }
}